#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

class Line
{
/* public: */
    class Point{
    public:
        Point(int x,int y)
        : _ix(x)
        , _iy(y)
        {}

        void print() const{
            cout << "(" << _ix
                << "," << _iy
                << ")";
        }
    friend ostream & operator<<(ostream & os,const Line::Point & rhs);
    private:
        int _ix;
        int _iy;
    };
public:
    Line(int x1, int y1, int x2, int y2)
    : _pt1(x1,y1)
    , _pt2(x2,y2)
    {}

    void printLine() const{
        _pt1.print();
        cout << "---->";
        _pt2.print();
        cout << endl;
    }

    //输出流运算符处理Line对象
    friend ostream & operator<<(ostream & os, const Line & rhs);
    //输出流运算符处理Point对象
    //因为Point定义在Line的私有区域，所以还需要在Line中进行友元声明
    friend ostream & operator<<(ostream & os,const Line::Point & rhs);
    friend Point showLinePt(const Line & rhs);
private: 
    Point _pt1;
    Point _pt2;
    double _length = 10;
};

ostream & operator<<(ostream & os, const Line & rhs){
    os << rhs._pt1 << "---->" << rhs._pt2;
    return os;
}


//输出流运算符对Point对象进行重载
//函数体中访问了Point的私有成员，所以要将这个函数声明为Point的友元
//如果Point定义在Line的私有区域
//那么Point对象不能直接访问，甚至在函数声明中都不能写
ostream & operator<<(ostream & os,const Line::Point & rhs){
    os << "(" << rhs._ix << "," << rhs._iy << ")";
    return os;
}

Line::Point showLinePt(const Line & rhs){
    return rhs._pt1;
}

#if 0
void test0(){
    Line ll(1,2,3,4);
    //内部类创建对象时要加上外部类的作用域
    //如果内部类定义在外部类的私有区域
    //则无法在外部类之外创建内部类对象
    Line::Point pt(8,9);

    cout << pt << endl;
    cout << ll << endl;

    cout << sizeof(pt) << endl;
    cout << sizeof(ll) << endl;
}
#endif

void test1(){
    Line ll(1,2,3,4);
    /* Line::Point pt(8,9); */
    cout << ll << endl;

    cout << showLinePt(ll) << endl;

}

int main(void){
    test1();
    return 0;
}
